package com.c2b.algorithm.leetcode.base;

import java.util.HashSet;
import java.util.Set;

/**
 * <a href='https://leetcode.cn/problems/count-vowel-substrings-of-a-string/'>统计字符串中的元音子字符串(Count Vowel Substrings of a String)</a>
 * <p>子字符串 是字符串中的一个连续（非空）的字符序列。</p>
 * <p>元音子字符串 是 仅 由元音（'a'、'e'、'i'、'o' 和 'u'）组成的一个子字符串，且必须包含 全部五种 元音。</p>
 * <p>给你一个字符串 word ，统计并返回 word 中 元音子字符串的数目 。</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例 1：
 *      输入：word = "aeiouu"
 *      输出：2
 *      解释：下面列出 word 中的元音子字符串（斜体加粗部分）：
 *          - "aeiouu"
 *          - "aeiouu"
 *
 * 示例 2：
 *      输入：word = "unicornarihan"
 *      输出：0
 *      解释：word 中不含 5 种元音，所以也不会存在元音子字符串。
 *
 * 示例 3：
 *      输入：word = "cuaieuouac"
 *      输出：7
 *      解释：下面列出 word 中的元音子字符串（斜体加粗部分）：
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *          - "cuaieuouac"
 *
 * 示例 4：
 *      输入：word = "bbaeixoubb"
 *      输出：0
 *      解释：所有包含全部五种元音的子字符串都含有辅音，所以不存在元音子字符串。
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 * <ul>
 *     <li>1 <= word.length <= 100</li>
 *     <li>word 仅由小写英文字母组成</li>
 * </ul>
 * </p>
 *
 * @author c2b
 * @since 2024/1/19 9:45
 */
public class LC2062CountVowelSubstringsOfString_S {
    static class Solution {
        public int countVowelSubstrings(String word) {
            int length = word.length();
            if (length < 5) {
                return 0;
            }
            // int 共 32位，字母共26个。用一个整数表示元音字母的状态
            // 00000000 0001(u)0000 01(o)000001(i) 0001(e)0001(a)
            int vowelState = 1 | 1 << 4 | 1 << 8 | 1 << 14 | 1 << 20;
            int res = 0;
            for (int i = 0; i < length; i++) {
                int mask = 0;
                for (int j = i; j < length; j++) {
                    char currCh = word.charAt(j);
                    // (vowelState & (1 << currCh - 'a'))) == 1 : 是元音字母
                    // (vowelState & (1 << currCh - 'a'))) == 0 : 非元音字母
                    if ((vowelState & (1 << currCh - 'a')) == 0) {
                        break;
                    }
                    mask |= (1 << currCh - 'a');
                    if (mask == vowelState) {
                        ++res;
                    }
                }
            }
            return res;
        }

        public int countVowelSubstrings2(String word) {
            int length = word.length();
            if (length < 5) {
                return 0;
            }
            int res = 0;
            for (int i = 0; i < length; i++) {
                Set<Character> characterSet = new HashSet<>();
                for (int j = i; j < length; j++) {
                    if ((!isVowel(word.charAt(j)))) {
                        break;
                    }
                    characterSet.add(word.charAt(j));
                    if (characterSet.size() == 5) {
                        ++res;
                    }
                }
            }
            return res;
        }

        private boolean isVowel(char ch) {
            return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.countVowelSubstrings("aeiouu"));
        System.out.println(solution.countVowelSubstrings("unicornarihan"));
        System.out.println(solution.countVowelSubstrings("cuaieuouac"));
    }
}
